import pyaudio
import numpy as np
import wave
from scipy import signal

def count_hits(audio_data):
    max_value = np.max(audio_data)  # 音频数据的最大值
    threshold = 0.7 * max_value  # 70%峰值阈值
    
    # 统计超过阈值的数量
    hits = np.sum(audio_data > threshold)
    
    return hits

def record_audio(fs, duration, output_file):
    audio = pyaudio.PyAudio()

    # 打开音频输入流
    stream = audio.open(format=pyaudio.paInt16,
                        channels=1,
                        rate=fs,
                        input=True,
                        frames_per_buffer=1024)

    frames = []
    for i in range(int(fs / 1024 * duration)):
        # 读取音频数据
        data = stream.read(1024)
        frames.append(data)

    # 关闭流和音频
    stream.stop_stream()
    stream.close()
    audio.terminate()

    # 将帧数据合并为一个连续的数组
    audio_data = np.frombuffer(b"".join(frames), dtype=np.int16)
    
    # 将音频数据保存到WAV文件中（不降采样）
    with wave.open(output_file, "wb") as wav_file:
        wav_file.setnchannels(1)  # 单声道
        wav_file.setsampwidth(audio.get_sample_size(pyaudio.paInt16))  # 采样宽度
        wav_file.setframerate(fs)  # 原始采样率
        wav_file.writeframes(audio_data.tobytes())
    
    return audio_data

def smooth_waveform(audio_data, target_samples):
    # 计算每个目标样本的下标范围
    indices = np.linspace(0, len(audio_data)-1, target_samples, dtype=int)
    
    # 平滑波形
    smoothed_data = np.zeros(target_samples)
    for i, index in enumerate(indices):
        if i == len(indices) - 1:
            smoothed_data[i] = audio_data[index]
        else:
            smoothed_data[i] = np.mean(audio_data[index:indices[i+1]])
    
    return smoothed_data

def plot_waveform(audio_data):
    scale_factor = 100
    
    # 缩放音频数据到合适的范围
    normalized_data = audio_data / np.max(np.abs(audio_data))
    
    # 缩小音频数据范围并调整为整数
    scaled_data = np.round((normalized_data * scale_factor)).astype(int)
    
    # 绘制波形
    for sample in scaled_data:
        print("#" * sample)

fs = 44100  # 采样率
duration = 1  # 录制时长（秒）
output_file = "recorded_audio.wav"
target_samples = 100  # 目标样本点数量

print("1秒钟内敲击计数开始...")

# 录制音频数据并保存到文件（不降采样）
audio_data = record_audio(fs, duration, output_file)

# 计算明显超过阈值的次数
hits = count_hits(audio_data)

print(f"\n敲击次数: {hits}")

print("\n绘制平滑后的音频波形：")
# 平滑并绘制音频波形
smoothed_data = smooth_waveform(audio_data, target_samples)
plot_waveform(smoothed_data)

print("\n重放录制的音频...")
# 重放录制的音频
play_audio(fs, output_file)
